'''
Created on 2010/07/06

@author: yukiyonezawa
'''

from pyrfid.Util.Util import Util
import sys
from pyrfid.DataProtocol.LogicalMemory.DataSet import DataSet
import binascii
import time
from pyrfid.DataProtocol.LogicalMemory import LogicalMemory
from pyrfid.asn1.Encoder import Encoder
from pyrfid.DataProtocol.DSFID.DataFormat.DataFormatUtil import DataFormatUtil
from pyrfid.DataProtocol.AddObject import AddObject
from pyrfid.DataProtocol.DSFID.Processor.Decompactor import Decompactor
from pyrfid.asn1.Decoder import Decoder


class RootOIDEncoded(object):
    
    DATA_FORMAT_ID = 2
    
    ISO_15434 = "1 0 15434"
    ISO_6523 = "1 0 6523" 
    ISO_15459 = "1 0 15459"
    LIBRARY_LOAN_ITEMS = "1 0 15961 6"
    ISO_15962_COMBINED = "1 0 15961"
    DATA_IDENTIFIER_ALGORITHM ="1 0 15961 10"
    IATA_BAGGAGE = "1 0 15961 12"
    
    #this is test code
    ISO_15961_9 = "1 0 15961 9"
    
    ROOT_OID = ""    
    ROOT_OID_LIST = {"3":ISO_15434, "4":ISO_6523, "5":ISO_15459, "6":LIBRARY_LOAN_ITEMS, "8":ISO_15962_COMBINED, "10":DATA_IDENTIFIER_ALGORITHM, "12":IATA_BAGGAGE, "9":ISO_15961_9}
        
    def __init__(self):
        pass
    
    def formattingDataSet(self, existing_data_set_list, add_data_set_list):
        
        isNewAddDataSet = False
        
        encoded_root_OID = ""
        #calculate root oid        
        if len(existing_data_set_list) > 0:
            encoded_root_OID  = existing_data_set_list[0].OBJECT_IDENTIFIER
        else:
            #for new data-set
            isNewAddDataSet = True                
            encoded_root_OID = self.__getRootOID(add_data_set_list)
        
        add_data_set_list = self.__rootOIDFormat(add_data_set_list, encoded_root_OID)
        add_data_set_list = DataFormatUtil.encodeLengthOfIdentifier(add_data_set_list)
        
        return_add_data_set_list = list()
        #create root OID
        if isNewAddDataSet == True:
            data_set = DataSet()
            data_set.OBJECT_IDENTIFIER = encoded_root_OID
            precursor = Util.convertIntToBit(len(encoded_root_OID) / 2, 7)
            data_set.PRECURSOR =  "0" + precursor
            data_set.LENGTH_OF_OBJECT = "00"
            return_add_data_set_list.append(data_set)
        
        for data_set in existing_data_set_list:
            return_add_data_set_list.append(data_set)        
        for data_set in add_data_set_list:
            return_add_data_set_list.append(data_set)
                
        return return_add_data_set_list        

    def __rootOIDFormat(self, add_data_set_list, encoded_root_OID):        
        for data_set in add_data_set_list:
            print encoded_root_OID
            print data_set.OBJECT_IDENTIFIER[:len(encoded_root_OID)]
            if encoded_root_OID != data_set.OBJECT_IDENTIFIER[:len(encoded_root_OID)]:
                raise " A OBJECT IDETNFIER does not match Root "
            data_set.OBJECT_IDENTIFIER = data_set.OBJECT_IDENTIFIER[len(encoded_root_OID):]
        return add_data_set_list
    
    def __getRootOID(self, add_data_set_list):
        """docstring for getRootOid"""
        print add_data_set_list
        
        minLength = len(add_data_set_list[0].OBJECT_IDENTIFIER)
        if len(add_data_set_list) <= 1:
            return ""
        
        for index in range(1, len(add_data_set_list)):
            tempMinLength = len(add_data_set_list[index].OBJECT_IDENTIFIER)
            if minLength > tempMinLength:
                minLength = tempMinLength
        
        sameOfobjectIdentifierIndex = 0
    
        for objectIdentifierIndex in range(1, minLength / 2):
            value = add_data_set_list[0].OBJECT_IDENTIFIER[:objectIdentifierIndex*2]
            same = True
            for index in range(1, len(add_data_set_list)):
                if value != add_data_set_list[index].OBJECT_IDENTIFIER[:objectIdentifierIndex*2]:
                    same = False
            if same == True:
                sameOfobjectIdentifierIndex += 1
    
        rootOID = add_data_set_list[0].OBJECT_IDENTIFIER[:sameOfobjectIdentifierIndex*2]
        return rootOID
    
    def decodeDataSetToAddData(self, data_set_list):
        
        add_objects_list = []
        #root-OID
        root_object_identifier = data_set_list[0].OBJECT_IDENTIFIER
        data_set_list = data_set_list[1:]
        
        for data_set in data_set_list:            
            suffix_object_identifier = ""
            if data_set.OBJECT_IDENTIFIER != "":
                suffix_object_identifier = data_set.OBJECT_IDENTIFIER
            else:
                suffix_object_identifier = int(data_set.PRECURSOR[4:], 2)
                        
            encoded_object_identifier = root_object_identifier + suffix_object_identifier             
            object_compaction_type = data_set.getCompactionType()
            object_value = Decompactor.decompactObject(object_compaction_type, data_set.OBJECT)
            add_objects_list.append(AddObject(encoded_object_identifier, False, object_value, AddObject.COMPACT, False))
        
        return add_objects_list
    
    def decodePrecursorRootOID(self, root_OID_precursor):
        bit = Util.convertHexToBit(root_OID_precursor)
        isOffset = False
        if bit[0] == "1":
            isOffset = True        
        return {"is_offset":isOffset, "length_of_object_identifier":int(bit[1:], 2)}
    
    
        